#ifndef NODE_MANAGER_H
#define NODE_MANAGER_H

#include "etcd_client.h"
#include <string>
#include <vector>
#include <thread>
#include <functional>
#include <atomic>
#include <chrono>
#include <mutex>
#include <map>

// 节点状态
enum class NodeStatus {
    UNKNOWN,    // 未知状态
    FOLLOWER,   // 从节点
    LEADER,     // 主节点
    FAULT       // 故障
};

// 节点信息
struct NodeInfo {
    std::string id;                             // 节点ID
    std::string endpoint;                       // 节点终端点
    NodeStatus status;                          // 节点状态
    std::chrono::system_clock::time_point joinTime;      // 加入时间
    std::chrono::system_clock::time_point lastHeartbeat; // 最后心跳时间
};

/**
 * 节点管理器类
 * 负责管理节点生命周期和状态
 */
class NodeManager {
public:
    /**
     * 构造函数
     * @param etcdUrl ETCD服务器URL
     * @param nodeId 节点ID
     * @param endpoint 节点终端点
     */
    NodeManager(const std::string& etcdUrl, const std::string& nodeId, const std::string& endpoint);
    
    /**
     * 析构函数
     */
    ~NodeManager();
    
    /**
     * 初始化节点
     * @return 是否成功
     */
    bool init();
    
    /**
     * 启动节点
     * @return 是否成功
     */
    bool start();
    
    /**
     * 停止节点
     */
    void stop();
    
    /**
     * 获取所有节点
     * @return 节点列表
     */
    std::vector<NodeInfo> getAllNodes() const;
    
    /**
     * 获取当前节点ID
     * @return 节点ID
     */
    std::string getCurrentNodeId() const;
    
    /**
     * 获取当前节点信息
     * @return 节点信息
     */
    NodeInfo getCurrentNodeInfo() const;
    
    /**
     * 获取主节点
     * @param leaderId 主节点ID（输出）
     * @param leaderInfo 主节点信息（输出）
     * @return 是否成功获取主节点信息
     */
    bool getLeaderNode(std::string& leaderId, NodeInfo& leaderInfo);
    
    /**
     * 获取主节点（向后兼容旧接口）
     * @return 主节点信息
     */
    NodeInfo getLeaderNode() const;
    
    /**
     * 获取当前节点状态
     * @return 节点状态
     */
    NodeStatus getStatus() const;
    
    /**
     * 注册状态变更回调
     * @param callback 回调函数
     */
    void registerStatusCallback(std::function<void(NodeStatus, NodeStatus)> callback);
    
    /**
     * 注册节点加入回调
     * @param callback 回调函数
     */
    void registerNodeJoinCallback(std::function<void(const NodeInfo&)> callback);
    
    /**
     * 注册节点离开回调
     * @param callback 回调函数
     */
    void registerNodeLeaveCallback(std::function<void(const NodeInfo&)> callback);
    
    /**
     * 模拟节点故障
     * @return 是否成功
     */
    bool simulateFault();
    
    /**
     * 模拟节点恢复
     * @return 是否成功
     */
    bool simulateRecover();

private:
    // 创建租约
    bool createLease();
    
    // 续约
    bool renewLease();
    
    // 撤销租约
    void revokeLease();
    
    // 注册节点
    bool registerNode();
    
    // 注销节点
    void unregisterNode();
    
    // 更新节点信息
    bool updateNodeInfo();
    
    // 更新状态
    void updateStatus(NodeStatus newStatus);
    
    // 心跳循环
    void heartbeatLoop();
    
    // 选举循环
    void electionLoop();
    
    // 尝试成为主节点
    bool tryBecomeLeader();
    
    // 检查主节点健康状态
    void checkLeaderHealth(const std::string& leaderId);
    
    // 序列化节点信息
    std::string serializeNodeInfo() const;
    
    // 反序列化节点信息
    bool deserializeNodeInfo(const std::string& json, NodeInfo& nodeInfo) const;
    
    // 将节点状态转换为字符串
    std::string nodeStatusToString(NodeStatus status) const;

    // 序列化节点基本信息（用于持久化存储）
    std::string serializeBasicNodeInfo() const;
    
    // 加载持久化节点信息
    void loadPersistentNodeInfo();
    
    // 保存持久化节点信息
    bool savePersistentNodeInfo();
    
    // 获取所有持久化节点信息
    std::vector<NodeInfo> getAllPersistentNodes() const;

private:
    // 常量
    static constexpr int HEARTBEAT_INTERVAL = 5;     // 心跳间隔（秒）
    static constexpr int ELECTION_INTERVAL = 7;      // 选举间隔（秒）
    static constexpr int LEASE_TTL = 30;             // 租约TTL（秒）
    static constexpr const char* NODE_PREFIX = "/nodes/";   // 节点键前缀
    static constexpr const char* LEADER_KEY = "/leader";    // 主节点键
    static constexpr const char* PERSISTENT_NODE_PREFIX = "/persistent_nodes/";  // 持久化节点键前缀

    // 成员变量
    std::string m_etcdUrl;                    // ETCD服务器URL
    std::string m_nodeId;                     // 节点ID
    std::string m_endpoint;                   // 节点终端点
    NodeStatus m_status;                      // 节点状态
    std::chrono::system_clock::time_point m_joinTime;       // 加入时间
    std::chrono::system_clock::time_point m_lastHeartbeat;  // 最后心跳时间
    std::atomic<bool> m_running;              // 运行标志
    EtcdClient* m_etcdClient;                 // ETCD客户端
    int64_t m_leaseId;                        // 租约ID
    std::thread m_heartbeatThread;            // 心跳线程
    std::thread m_electionThread;             // 选举线程
    std::function<void(NodeStatus, NodeStatus)> m_statusCallback; // 状态变更回调
    std::function<void(const NodeInfo&)> m_nodeJoinCallback;      // 节点加入回调
    std::function<void(const NodeInfo&)> m_nodeLeaveCallback;     // 节点离开回调
    mutable std::mutex m_mutex;               // 互斥锁
};

#endif // NODE_MANAGER_H 